""" A Qt API selector that can be used to switch between PyQt and PySide.
"""
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import six

import os
from matplotlib import rcParams, verbose

# Available APIs.
QT_API_PYQT = 'PyQt4'       # API is not set here; Python 2.x default is V 1
QT_API_PYQTv2 = 'PyQt4v2'   # forced to Version 2 API
QT_API_PYSIDE = 'PySide'    # only supports Version 2 API
QT_API_PYQT5 = 'PyQt5'       # use PyQt5 API; Version 2 with module shim

ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4),
           pyqt5=(QT_API_PYQT5, 5))
# ETS is a dict of env variable to (QT_API, QT_MAJOR_VERSION)
# If the ETS QT_API environment variable is set, use it, but only
# if the varible if of the same major QT version.  Note that
# ETS requires the version 2 of PyQt4, which is not the platform
# default for Python 2.x.

QT_API_ENV = os.environ.get('QT_API')

if rcParams['backend'] == 'Qt5Agg':
    QT_RC_MAJOR_VERSION = 5
else:
    QT_RC_MAJOR_VERSION = 4

QT_API = None

if (QT_API_ENV is not None):
    try:
        QT_ENV_MAJOR_VERSION = ETS[QT_API_ENV][1]
    except KeyError:
        raise RuntimeError(
            ('Unrecognized environment variable %r, valid values are:'
             ' %r, %r or %r' % (QT_API_ENV, 'pyqt', 'pyside', 'pyqt5')))
    if QT_ENV_MAJOR_VERSION == QT_RC_MAJOR_VERSION:
        # Only if backend and env qt major version are
        # compatible use the env variable.
        QT_API = ETS[QT_API_ENV][0]

if QT_API is None:
    # No ETS environment or incompatible so use rcParams.
    if rcParams['backend'] == 'Qt5Agg':
        QT_API = rcParams['backend.qt5']
    else:
        QT_API = rcParams['backend.qt4']

# We will define an appropriate wrapper for the differing versions
# of file dialog.
_getSaveFileName = None

# Flag to check if sip could be imported
_sip_imported = False

# Now perform the imports.
if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYQT5):
    try:
        import sip
        _sip_imported = True
    except ImportError:
        # Try using PySide
        QT_API = QT_API_PYSIDE

if _sip_imported:
    if QT_API == QT_API_PYQTv2:
        if QT_API_ENV == 'pyqt':
            cond = ("Found 'QT_API=pyqt' environment variable. "
                    "Setting PyQt4 API accordingly.\n")
        else:
            cond = "PyQt API v2 specified."
        try:
            sip.setapi('QString', 2)
        except:
            res = 'QString API v2 specification failed. Defaulting to v1.'
            verbose.report(cond + res, 'helpful')
            # condition has now been reported, no need to repeat it:
            cond = ""
        try:
            sip.setapi('QVariant', 2)
        except:
            res = 'QVariant API v2 specification failed. Defaulting to v1.'
            verbose.report(cond + res, 'helpful')

    if QT_API in [QT_API_PYQT, QT_API_PYQTv2]:  # PyQt4 API

        from PyQt4 import QtCore, QtGui

        try:
            if sip.getapi("QString") > 1:
                # Use new getSaveFileNameAndFilter()
                _getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter
            else:

                # Use old getSaveFileName()
                def _getSaveFileName(*args, **kwargs):
                    return (QtGui.QFileDialog.getSaveFileName(*args, **kwargs),
                            None)

        except (AttributeError, KeyError):

            # call to getapi() can fail in older versions of sip
            def _getSaveFileName(*args, **kwargs):
                return QtGui.QFileDialog.getSaveFileName(*args, **kwargs), None

    else:  # PyQt5 API
        from PyQt5 import QtCore, QtGui, QtWidgets
        _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName

    # Alias PyQt-specific functions for PySide compatibility.
    QtCore.Signal = QtCore.pyqtSignal
    try:
        QtCore.Slot = QtCore.pyqtSlot
    except AttributeError:
        # Not a perfect match but works in simple cases
        QtCore.Slot = QtCore.pyqtSignature

    QtCore.Property = QtCore.pyqtProperty
    __version__ = QtCore.PYQT_VERSION_STR

else:  # try importing pyside
    from PySide import QtCore, QtGui, __version__, __version_info__
    if __version_info__ < (1, 0, 3):
        raise ImportError(
            "Matplotlib backend_qt4 and backend_qt4agg require PySide >=1.0.3")

    _getSaveFileName = QtGui.QFileDialog.getSaveFileName


# Apply shim to Qt4 APIs to make them look like Qt5
if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYSIDE):
    '''Import all used QtGui objects into QtWidgets

    Here I've opted to simple copy QtGui into QtWidgets as that
    achieves the same result as copying over the objects, and will
    continue to work if other objects are used.

    '''
    QtWidgets = QtGui
